#include <iostream>
#include <pthread.h>
#include <string>
#include <vector>
#include <unistd.h>
#include "myh/MyLog.hpp"
#include <cstring>
#include "PthreadMutex.hpp"
#include <time.h>
#define N 100000;
int test_i = N;
int test_j = N;
class PthreadDate
{
public:
    PthreadDate(){}

    PthreadDate(pthread_t tid,const std::string& pthreadname)
        :_tid(tid)
        ,_pthreadname(pthreadname)
    {}
    std::string& getpthreadname(){return _pthreadname;}
    pthread_t& gettid() {return _tid;}
    int& getnum(){return _num;}
private:
    pthread_t _tid;
    std::string _pthreadname;
    int _num;
};

void* pthreadtask(void* tmp)
{

    auto pd = static_cast<PthreadDate*>(tmp);
    while(true)
    {
        {
            Guardlock lock;
           if(test_i > 0)
            {
                std::cout << test_i <<std::endl;

                // std::cout << pd->getpthreadname() << "  i:" << test_i <<std::endl;
                test_i--;
            }
            else
            {
                break;
            }
        }
    }
    return nullptr;
}


void test1()
{
    std::vector<PthreadDate*> vpd;
    
    for(int i = 0;i < 20;i++)
    {
        pthread_t tid;
        PthreadDate* pd = new PthreadDate;
        pd->getnum() = i;
        int n = pthread_create(&tid,nullptr,pthreadtask,(void*)pd);
        if(n)
        {
            lg(Error,"[%d-%d-pthread_create]%s",__FILE__,__LINE__,strerror(n));
        }
        pd->gettid() = tid;
        std::string pthreadname = "pthread->" + std::to_string(pd->getnum())+ ":[" + std::to_string(pd->gettid()) +"]";
        pd->getpthreadname() = pthreadname;
        vpd.push_back(pd);
    }
    bool flag = false; 
    while(true)
    {
        for(auto pt : vpd)
        {
            flag = true;
            int n =pthread_join(pt->gettid(),nullptr);
            if(n)
            {
                lg(Error,"[%d-%d-pthread_join]%s",__FILE__,__LINE__,strerror(n));
            }
            // std::cout << pt->getpthreadname() << "  exit..."<< std::endl;
            delete pt;
        }   
        if(flag){break;}
    }
    
    // std::cout << test_i << std::endl;
}


void test2()
{
    while(true)
    {
        if(test_j > 0)
        {
            std::cout << test_j <<std::endl;
            test_j--;
        }
        else{break;}
    }
}

int main()
{
    struct timespec  a,b,c;
    clock_gettime(CLOCK_REALTIME,&a);
    test1();
    clock_gettime(CLOCK_REALTIME,&b);
    test2();
    clock_gettime(CLOCK_REALTIME,&c);
    long d = b.tv_nsec - a.tv_nsec;
    long e = c.tv_nsec - b.tv_nsec;

    printf("test1:[%ld]\n test2[%ld]\n",d,e);
    return 0;
}